package com.mars.base.common.utils.file;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import com.mars.base.common.utils.PropertyUtils;
import com.mars.base.common.utils.RandomUitl;
/**
 * 文件上传工具类，适合文件上传到当前项目中
 */
public class FileUtil extends FileCommonUtil implements Serializable {
	
	private static final long serialVersionUID = 1L;
	
	private static final Logger logger = LoggerFactory.getLogger(FileUtil.class) ;

	public static List<FileMeta> upload(HttpServletRequest request) {
		return upload(request, null) ;
	}
	public static List<FileMeta> upload(HttpServletRequest request, String destDir) {
		
		if(null == request) {
			throw new RuntimeException("HttpServletRequest 对象为空") ;
		}
		
		List<FileMeta> list = new ArrayList<FileMeta>() ;
		
		//文件上传的路径
		String uploadDestDir = null ;
		//文件上传的默认根路径
		String homeDir = PropertyUtils.getValue("UploadsHomeDir") ;
		
		if(null == homeDir || StringUtils.isEmpty(homeDir.trim())) {
			uploadDestDir = request.getServletContext().getRealPath(homeDir) ;
		}
		
		if(null != destDir && StringUtils.isNotEmpty(destDir.trim())) {
			uploadDestDir += FilenameUtils.separatorsToSystem(destDir + File.separator) ;
		} else {
			uploadDestDir = System.getProperty("java.io.tmpdir") + File.separator ;
		}
		if(!FileCommonUtil.checkFileExists(uploadDestDir)) {
			FileCommonUtil.createDir(uploadDestDir) ;
		}
		
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request ;
		
		//取得MultiValueMap集合
		MultiValueMap<String,MultipartFile> multiFileMap = multipartRequest.getMultiFileMap() ;
		Set<Entry<String, List<MultipartFile>>> entrySet = multiFileMap.entrySet() ;
		for (Entry<String, List<MultipartFile>> entry : entrySet) {
			
			//获取MultipartFile集合
			List<MultipartFile> multipartFiles = entry.getValue() ;
			for (MultipartFile multipartFile : multipartFiles) {
				//文件全名
				String fileName = multipartFile.getOriginalFilename() ;
				//文件类型
				String contentType = multipartFile.getContentType() ;
				//文件大小
				long size = multipartFile.getSize() ;
				//文件名称
				String baseName = FilenameUtils.getBaseName(fileName) ;
				//文件扩展名
				String extension = FilenameUtils.getExtension(fileName) ;
				//文件大小单位换算
				String convertUnitSize = FileSizeHelper.getHumanReadableFileSize(size) ;
				//文件上传到服务器的名称
				String newName = RandomUitl.uuid() + "." + extension ;
				//上传到服务器的路径+文件名称
				String destFilePath = FilenameUtils.separatorsToSystem(uploadDestDir + newName) ;
				//文件的相对路径
				String destBasePath = FilenameUtils.separatorsToUnix(homeDir + destDir + File.separator + newName) ;
				//服务器域名
				String originDomain = getDomain(request) ;
				//文件访问URL
				String fileUrl = originDomain + destBasePath ;
				
				try {
					FileCopyUtils.copy(multipartFile.getBytes(), new File(destFilePath));
				} catch (IOException e) {
					list.add(new FileMeta(false, "文件上传失败")) ;
					logger.error("文件上传失败", e);
				}
				
				list.add(new FileMeta(fileName, contentType, size, convertUnitSize, baseName, extension, newName, uploadDestDir, destFilePath, destBasePath, originDomain, fileUrl, true, "文件上传成功")) ;
				
			}
			
		}
		return list ;
	}
	
	
	/**
	 * 提取服务器URL地址
	 * 
	 * @param request
	 * @return
	 */
	public static String getDomain(HttpServletRequest request) {
		try {
			StringBuffer baseUrl = new StringBuffer();
			String scheme = request.getScheme();
			int port = request.getServerPort();
			
			baseUrl.append(scheme); // http, https
			baseUrl.append("://");
			baseUrl.append(request.getServerName());
			if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443)) {
				baseUrl.append(':');
				baseUrl.append(request.getServerPort());
			}
			return baseUrl.toString();
		} catch (NullPointerException e) {
			e.printStackTrace(); 
		}
		return null;
	}
}
